package com.portal.framework.common.lang;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

import com.portal.framework.util.ObjectUtil;

/**
 * <pre>
 * GroupRandom&lt;Integer&gt; rand = new GroupRandom&lt;Integer&gt;();
 * for (int i = 1; i &lt;= 5; i++) {
 * 	rand.add(new Integer(i), i); // add();
 * }
 * for (int j = 0; j &lt; 10; j++) {
 * 	System.out.println(j + &quot;: &quot; + rand.nextObject());
 * }
 * </pre>
 */
public class GroupRandom<V> {

	// 总权重

	private int totalRight;

	private LinkedList<IdValue<V>> group = new LinkedList<IdValue<V>>();

	private Random randSeed = null;

	public GroupRandom() {
		super();
	}

	public Random getRandSeed() {
		return randSeed;
	}

	public void setRandSeed(Random randSeed) {
		this.randSeed = randSeed;
	}

	public int add(V which, int right) {
		if (right > 0) {
			group.add(new IdValue<V>(right, which));
			totalRight += right;
		}
		return totalRight;
	}

	public void remove(V which, boolean removeAll) {
		Iterator<IdValue<V>> it = group.iterator();
		while (it.hasNext()) {
			IdValue<V> iv = it.next();
			if (ObjectUtil.equals(iv.getValue(), which)) {
				it.remove();
				totalRight -= iv.getId().intValue();
				if (!removeAll)
					return;
			}
		}
	}

	public void remove(V which) {
		remove(which, true);
	}

	public void clear() {
		totalRight = 0;
		group.clear();
	}

	/**
	 * 根据权重随机得到一个对象
	 * 
	 * @param rand
	 * @return
	 */
	public V nextObject() {
		if (totalRight == 0)
			return null;
		if (group.isEmpty())
			return null;
		if (group.size() == 1) {
			return group.getFirst().getValue();
		}
		if (randSeed == null) {
			randSeed = new Random();
		}
		return nextObject(randSeed.nextInt(totalRight));
	}

	/**
	 * 根据权重得到下一个对象
	 * 
	 * @param rand
	 * @return
	 */
	public V nextObject(int rand) {
		if (totalRight == 0)
			return null;
		if (group.isEmpty())
			return null;
		if (group.size() == 1) {
			return group.get(0).getValue();
		}
		if (rand < 0)
			rand = -rand;
		if (rand > totalRight)
			rand = rand % totalRight;
		for (IdValue<V> iv : group) {
			if (rand < iv.getId().intValue())
				return iv.getValue();
			rand -= iv.getId().intValue();
		}
		return group.getLast().getValue();
	}

	public int getTotalRight() {
		return totalRight;
	}

	public int size() {
		return group.size();
	}

	public boolean isEmpty() {
		return group.isEmpty();
	}
}